import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';

class CreateExtension extends StatefulWidget {
  const CreateExtension({super.key});

  @override
  State<CreateExtension> createState() => _CreateExtensionState();
}

class _CreateExtensionState extends State<CreateExtension> {
  String _name = "";
  String _lang = "";
  String _baseUrl = "";
  String _apiUrl = "";
  String _iconUrl = "";
  String _notes = "";
  int _sourceTypeIndex = 0;
  int _itemTypeIndex = 0;
  int _languageIndex = 0;
  final List<String> _sourceTypes = ["single", "multi", "torrent"];
  final List<String> _itemTypes = ["Manga", "Anime", "Novel"];
  final List<String> _languages = [
    "Dart",
    "JavaScript",
    "LNReader compiled JS",
  ];
  SourceCodeLanguage _sourceCodeLanguage = SourceCodeLanguage.dart;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Create Extension")),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 17),
                child: Row(
                  children: [
                    const Text("Choose extension language"),
                    const SizedBox(width: 20),
                    Flexible(
                      child: DropdownButton(
                        icon: const Icon(Icons.keyboard_arrow_down),
                        isExpanded: true,
                        value: _languageIndex,
                        hint: Text(
                          _languages[_languageIndex],
                          style: const TextStyle(fontSize: 13),
                        ),
                        items: _languages
                            .map(
                              (e) => DropdownMenuItem(
                                value: _languages.indexOf(e),
                                child: Text(
                                  e,
                                  style: const TextStyle(fontSize: 13),
                                ),
                              ),
                            )
                            .toList(),
                        onChanged: (v) {
                          setState(() {
                            if (v == 0) {
                              _sourceCodeLanguage = SourceCodeLanguage.dart;
                            } else if (v == 1) {
                              _sourceCodeLanguage =
                                  SourceCodeLanguage.javascript;
                            } else {
                              _sourceCodeLanguage = SourceCodeLanguage.lnreader;
                            }
                            _languageIndex = v!;
                          });
                        },
                      ),
                    ),
                  ],
                ),
              ),
              _textEditing("Name", context, "ex: myAnime", (v) {
                setState(() {
                  _name = v;
                });
              }),
              _textEditing("Lang", context, "ex: en", (v) {
                setState(() {
                  _lang = v;
                });
              }),
              _textEditing("BaseUrl", context, "ex: https://example.com", (v) {
                setState(() {
                  _baseUrl = v;
                });
              }),
              _textEditing(
                "ApiUrl (optional)",
                context,
                "ex: https://api.example.com",
                (v) {
                  setState(() {
                    _apiUrl = v;
                  });
                },
              ),
              _textEditing("iconUrl", context, "Source icon url", (v) {
                setState(() {
                  _iconUrl = v;
                });
              }),
              _textEditing(
                "notes",
                context,
                "ex: this extension requires login",
                (v) {
                  setState(() {
                    _notes = v;
                  });
                },
              ),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 17),
                child: Row(
                  children: [
                    const Text("Type"),
                    const SizedBox(width: 20),
                    Flexible(
                      child: DropdownButton(
                        icon: const Icon(Icons.keyboard_arrow_down),
                        isExpanded: true,
                        value: _sourceTypeIndex,
                        hint: Text(
                          _sourceTypes[_sourceTypeIndex],
                          style: const TextStyle(fontSize: 13),
                        ),
                        items: _sourceTypes
                            .map(
                              (e) => DropdownMenuItem(
                                value: _sourceTypes.indexOf(e),
                                child: Text(
                                  e,
                                  style: const TextStyle(fontSize: 13),
                                ),
                              ),
                            )
                            .toList(),
                        onChanged: (v) {
                          setState(() {
                            _sourceTypeIndex = v!;
                          });
                        },
                      ),
                    ),
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 17),
                child: Row(
                  children: [
                    const Text("Target"),
                    const SizedBox(width: 20),
                    Flexible(
                      child: DropdownButton(
                        icon: const Icon(Icons.keyboard_arrow_down),
                        isExpanded: true,
                        value: _itemTypeIndex,
                        hint: Text(
                          _itemTypes[_itemTypeIndex],
                          style: const TextStyle(fontSize: 13),
                        ),
                        items: _itemTypes
                            .map(
                              (e) => DropdownMenuItem(
                                value: _itemTypes.indexOf(e),
                                child: Text(
                                  e,
                                  style: const TextStyle(fontSize: 13),
                                ),
                              ),
                            )
                            .toList(),
                        onChanged: (v) {
                          setState(() {
                            _itemTypeIndex = v!;
                          });
                        },
                      ),
                    ),
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Consumer(
                  builder: (context, ref, child) => ElevatedButton(
                    onPressed: () {
                      if (_name.isNotEmpty &&
                          _lang.isNotEmpty &&
                          _baseUrl.isNotEmpty &&
                          _iconUrl.isNotEmpty) {
                        try {
                          final id =
                              _sourceCodeLanguage == SourceCodeLanguage.dart
                              ? 'mangayomi-$_lang.$_name'.hashCode
                              : 'mangayomi-js-$_lang.$_name'.hashCode;
                          final checkIfExist = isar.sources.getSync(id);
                          if (checkIfExist == null) {
                            Source source = Source(
                              id: id,
                              name: _name,
                              lang: _lang,
                              baseUrl: _baseUrl,
                              apiUrl: _apiUrl,
                              iconUrl: _iconUrl,
                              typeSource: _sourceTypes[_sourceTypeIndex],
                              itemType: ItemType.values.elementAt(
                                _itemTypeIndex,
                              ),
                              isAdded: true,
                              isActive: true,
                              version: "0.0.1",
                              isNsfw: false,
                              notes: _notes,
                            )..sourceCodeLanguage = _sourceCodeLanguage;
                            source = source
                              ..isLocal = true
                              ..sourceCode =
                                  _sourceCodeLanguage == SourceCodeLanguage.dart
                                  ? _dartTemplate
                                  : _jsSample(source);
                            isar.writeTxnSync(() {
                              isar.sources.putSync(
                                source
                                  ..updatedAt =
                                      DateTime.now().millisecondsSinceEpoch,
                              );
                            });
                            Navigator.pop(context);
                            botToast("Source created successfully");
                          } else {
                            botToast("Source already exists");
                          }
                        } catch (e) {
                          botToast("Error when creating source");
                        }
                      }
                    },
                    child: Text(context.l10n.save),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Widget _textEditing(
  String label,
  BuildContext context,
  String hintText,
  void Function(String)? onChanged,
) {
  return Padding(
    padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 5),
    child: TextFormField(
      keyboardType: TextInputType.text,
      onChanged: onChanged,
      decoration: InputDecoration(
        hintText: hintText,
        labelText: label,
        isDense: true,
        filled: true,
        fillColor: Colors.transparent,
        enabledBorder: OutlineInputBorder(
          borderSide: BorderSide(color: context.secondaryColor),
        ),
        focusedBorder: OutlineInputBorder(
          borderSide: BorderSide(color: context.secondaryColor),
        ),
        border: OutlineInputBorder(
          borderSide: BorderSide(color: context.secondaryColor),
        ),
      ),
    ),
  );
}

const _dartTemplate = r'''
import 'package:mangayomi/bridge_lib.dart';
import 'dart:convert';

class TestSource extends MProvider {
  TestSource({required this.source});

  MSource source;

  final Client client = Client();

  @override
  bool get supportsLatest => true;

  @override
  Map<String, String> get headers => {};
  
  @override
  Future<MPages> getPopular(int page) async {
    // TODO: implement
  }

  @override
  Future<MPages> getLatestUpdates(int page) async {
    // TODO: implement
  }

  @override
  Future<MPages> search(String query, int page, FilterList filterList) async {
    // TODO: implement
  }

  @override
  Future<MManga> getDetail(String url) async {
    // TODO: implement
  }
  
  // For novel html content
  @override
  Future<String> getHtmlContent(String name, String url) async {
    // TODO: implement
  }
  
  // Clean html up for reader
  @override
  Future<String> cleanHtmlContent(String html) async {
    // TODO: implement
  }
  
  // For anime episode video list
  @override
  Future<List<MVideo>> getVideoList(String url) async {
    // TODO: implement
  }

  // For manga chapter pages
  @override
  Future<List<String>> getPageList(String url) async{
    // TODO: implement
  }

  @override
  List<dynamic> getFilterList() {
    // TODO: implement
  }

  @override
  List<dynamic> getSourcePreferences() {
    // TODO: implement
  }
}

TestSource main(MSource source) {
  return TestSource(source:source);
}''';

String _jsSample(Source source) =>
    '''
const mangayomiSources = [{
    "name": "${source.name}",
    "lang": "${source.lang}",
    "baseUrl": "${source.baseUrl}",
    "apiUrl": "${source.apiUrl}",
    "iconUrl": "${source.iconUrl}",
    "typeSource": "${source.typeSource}",
    "itemType": ${source.itemType.index},
    "version": "${source.version}",
    "pkgPath": "",
    "notes": ""
}];

class DefaultExtension extends MProvider {
    getHeaders(url) {
        throw new Error("getHeaders not implemented");
    }
    async getPopular(page) {
        throw new Error("getPopular not implemented");
    }
    get supportsLatest() {
        throw new Error("supportsLatest not implemented");
    }
    async getLatestUpdates(page) {
        throw new Error("getLatestUpdates not implemented");
    }
    async search(query, page, filters) {
        throw new Error("search not implemented");
    }
    async getDetail(url) {
        throw new Error("getDetail not implemented");
    }
    // For novel html content
    async getHtmlContent(name, url) {
        throw new Error("getHtmlContent not implemented");
    }
    // Clean html up for reader
    async cleanHtmlContent(html) {
        throw new Error("cleanHtmlContent not implemented");
    }
    // For anime episode video list
    async getVideoList(url) {
        throw new Error("getVideoList not implemented");
    }
    // For manga chapter pages
    async getPageList(url) {
        throw new Error("getPageList not implemented");
    }
    getFilterList() {
        throw new Error("getFilterList not implemented");
    }
    getSourcePreferences() {
        throw new Error("getSourcePreferences not implemented");
    }
}
''';
